import React, { useState } from 'react';
import { Modal, Table, InputNumber } from 'antd';
import * as echarts from 'echarts';
import { tableLocale } from '@/tool/components/PageEmpty';
import { TRAlert, TRMessage } from '#/components';
import { HttpCode } from '#/utils/contacts';
import { DragLineFunc } from '@/utils/utils';
import { configModal } from '@/assets';
import { Pointer } from '@/components';

import StationSelector from '../StationSelector';
import { saveRevisePrice } from './services';
import styles from './index.less';
import { getCssVariableValue } from '@/utils/utils';

const { Column } = Table;

/**
 * 自定义价格预测组件
 * date 预测标的日 必传
 * defaultStationIds 默认设置的场站id列表
 * defaultPointType 默认时点类型；只能为 '96' 或 '24' 必传
 * initLimitData 限价信息，长度必须与 defaultPointType 相同 必传，每个元素有max min两个属性
 * initData 长度必须与 defaultPointType 相同 必传
 * onChange 回调函数
 * provinceId 选中省份id
 * tradeSequenceId 交易序列id
 */
export default function CustomPriceForecast({
  date,
  defaultStationIds = [],
  defaultPointType,
  initLimitData,
  initData,
  onRef,
  onChange = () => {},
  provinceId,
  tradeSequenceId,
  version,
}) {
  React.useImperativeHandle(onRef, () => ({
    initHandle,
  }));

  // x轴包含 96 和 24 两种类型
  const xAxisData = {
    96: [
      '0015',
      '0030',
      '0045',
      '0100',
      '0115',
      '0130',
      '0145',
      '0200',
      '0215',
      '0230',
      '0245',
      '0300',
      '0315',
      '0330',
      '0345',
      '0400',
      '0415',
      '0430',
      '0445',
      '0500',
      '0515',
      '0530',
      '0545',
      '0600',
      '0615',
      '0630',
      '0645',
      '0700',
      '0715',
      '0730',
      '0745',
      '0800',
      '0815',
      '0830',
      '0845',
      '0900',
      '0915',
      '0930',
      '0945',
      '1000',
      '1015',
      '1030',
      '1045',
      '1100',
      '1115',
      '1130',
      '1145',
      '1200',
      '1215',
      '1230',
      '1245',
      '1300',
      '1315',
      '1330',
      '1345',
      '1400',
      '1415',
      '1430',
      '1445',
      '1500',
      '1515',
      '1530',
      '1545',
      '1600',
      '1615',
      '1630',
      '1645',
      '1700',
      '1715',
      '1730',
      '1745',
      '1800',
      '1815',
      '1830',
      '1845',
      '1900',
      '1915',
      '1930',
      '1945',
      '2000',
      '2015',
      '2030',
      '2045',
      '2100',
      '2115',
      '2130',
      '2145',
      '2200',
      '2215',
      '2230',
      '2245',
      '2300',
      '2315',
      '2330',
      '2345',
      '2400',
    ],
    24: [
      '0100',
      '0200',
      '0300',
      '0400',
      '0500',
      '0600',
      '0700',
      '0800',
      '0900',
      '1000',
      '1100',
      '1200',
      '1300',
      '1400',
      '1500',
      '1600',
      '1700',
      '1800',
      '1900',
      '2000',
      '2100',
      '2200',
      '2300',
      '2400',
    ],
  };
  const lineId = 'customPrice';

  const [showModal, setShowModal] = useState(false),
    [pointType, setPointType] = useState(null),
    [selectedStationIds, setSelectedStationIds] = useState([]),
    [hourData, setHourData] = useState([]),
    [limitData, setLimitData] = useState([]),
    [tableData, setTableData] = useState([]),
    [chartDomIns, setChartDomIns] = useState(null),
    [loading, setLoading] = useState(false),
    [hasModified, setHasModified] = useState(false);

  /**
   * 打开弹框时，初始化数据
   * 关闭弹框时，清空数据
   */
  React.useEffect(() => {
    if (showModal) {
      setPointType(defaultPointType);
      setSelectedStationIds(defaultStationIds);
      setHourData(initData.map((item) => item.toFixed(2)));
      setLimitData(initLimitData);
    } else {
      setPointType(null);
      setSelectedStationIds([]);
      setHourData([]);
      setLimitData([]);
      setTableData([]);
      chartDomIns?.dispose();
      setChartDomIns(null);
      setLoading(false);
      setHasModified(false);
    }
  }, [showModal]);

  /**
   * 切换时点类型
   * 如果与默认时点类型相同，则设置为默认时点数据；否则，重新计算时点数据
   */
  React.useEffect(() => {
    if (showModal) {
      if (defaultPointType === '24') {
        if (defaultPointType === pointType) {
          setHourData(initData.map((item) => item.toFixed(2)));
          setLimitData(initLimitData);
        } else {
          let data = [],
            localLimitData = [];
          for (let i = 0; i < 96; i++) {
            let originIndex = parseInt(i / 4);
            data.push(initData(originIndex));
            localLimitData.push(initLimitData(originIndex));
          }
          setHourData(data);
          setLimitData(localLimitData);
        }
      } else if (defaultPointType === '96') {
        if (defaultPointType === pointType) {
          setHourData(initData.map((item) => item.toFixed(2)));
          setLimitData(initLimitData);
        } else {
          let data = [],
            localLimitData = [];
          for (let i = 0; i < 24; i++) {
            data.push(
              (
                (initData[i * 4] +
                  initData[i * 4 + 1] +
                  initData[i * 4 + 2] +
                  initData[i * 4 + 3]) /
                4
              ).toFixed(2),
            );
            localLimitData.push({
              max: Math.min(
                initLimitData[i * 4].max,
                initLimitData[i * 4 + 1].max,
                initLimitData[i * 4 + 2].max,
                initLimitData[i * 4 + 3].max,
              ),
              min: Math.max(
                initLimitData[i * 4].min,
                initLimitData[i * 4 + 1].min,
                initLimitData[i * 4 + 2].min,
                initLimitData[i * 4 + 3].min,
              ),
            });
          }
          setHourData(data);
          setLimitData(localLimitData);
        }
      }
    }
  }, [showModal, pointType]);

  /**
   * 当打开弹框或者时点数据长度发生变化时，重新初始化echarts图
   */
  React.useEffect(() => {
    if (showModal && hourData.length === limitData.length) {
      // 放在宏任务队列里，等dom加载好再初始化echarts
      setTimeout(() => {
        initEchart();
      });
    }
  }, [showModal, hourData.length, limitData.length]);

  /**
   * 当时点内容或者长度发生变化时，重新生成table数据
   */
  React.useEffect(() => {
    if (showModal) {
      let tableDataObj = { index: 0 };
      xAxisData[pointType]?.forEach((item, index) => {
        tableDataObj[item] = hourData[index];
      });
      setTableData([tableDataObj]);
    }
  }, [showModal, JSON.stringify(hourData)]);

  const initHandle = () => {
    setShowModal(true);
  };

  /**
   * 更新 graphic 定位
   * @param {*} chartIns echarts 实例
   * @param {*} data y轴数据
   */
  const updatePosition = (chartIns, data) => {
    chartIns.setOption({
      graphic: echarts.util.map(data, function (item, dataIndex) {
        return {
          position: chartIns.convertToPixel({ seriesIndex: 0 }, [dataIndex, item]),
        };
      }),
    });
  };

  const initEchart = () => {
    chartDomIns && chartDomIns.dispose();

    var chartDom = document.getElementById('customEchart');
    var myChart = echarts.init(chartDom);
    var option = {
      color: ['#F5BE15'],
      grid: {
        left: '5%',
        right: '15',
        top: '30',
        bottom: '80',
      },
      tooltip: {
        trigger: 'axis',
        backgroundColor: '#161A1D',
        borderColor: 'transparent',
        textStyle: {
          color: '#A7A8A9',
        },
        formatter: (params) => {
          let str = `
           ${date.replaceAll('-', '')} ${params[0].name}
           <br />
           ${params[0].marker} 现货价格预测 ${parseFloat(params[0].data).toFixed(2)}元/MWh
          `;
          return str;
        },
      },
      dataZoom: [
        {
          type: 'slider',
          start: 0,
          end: 100,
          top: 410,
          height: 20,
          backgroundColor: getCssVariableValue('--bg-form'),
          dataBackground: {
            areaStyle: { opacity: 0 },
            lineStyle: { opacity: 0 },
          },
          selectedDataBackground: {
            lineStyle: { color: 'transparent' },
            areaStyle: {
              color: getCssVariableValue('--font-primary'),
              opacity: 0.2,
            },
          },
          borderColor: getCssVariableValue('--bg-form'),
          handleStyle: {
            color: getCssVariableValue('--font-primary'),
            borderColor: getCssVariableValue('--bd'),
          },
          /* moveHandleStyle: {
            color: '#EFF2F9',
          }, */
          brushSelect: false,
          showDetail: false,
        },
      ],
      xAxis: {
        type: 'category',
        nameTextStyle: {
          color: getCssVariableValue('--chart-font-color'),
        },
        data: xAxisData[pointType],
        axisLine: {
          lineStyle: {
            color: getCssVariableValue('--chart-x-line'),
          },
        },
        axisPointer: {
          lineStyle: {
            color: getCssVariableValue('--chart-font-color'),
            type: 'solid',
          },
        },
        axisLabel: {
          color: getCssVariableValue('--chart-font-color'),
        },
        axisTick: {
          alignWithLabel: true,
        },
      },
      yAxis: {
        type: 'value',
        nameTextStyle: {
          color: getCssVariableValue('--chart-font-color'),
        },
        // scale: true,
        axisLine: {
          show: false,
        },
        splitLine: {
          lineStyle: {
            color: getCssVariableValue('--chart-y-line'),
          },
        },
        axisLabel: {
          color: getCssVariableValue('--chart-font-color'),
        },
      },
      series: [
        {
          id: lineId,
          data: hourData,
          type: 'line',
          smooth: true,
          symbol: 'circle',
          symbolSize: 8,
          itemStyle: {
            // borderColor: '#222629',
            borderWidth: 1,
          },
          lineStyle: {
            width: 2,
          },
          emphasis: {
            lineStyle: {
              width: 2,
            },
          },
        },
      ],
    };
    myChart.setOption(option);
    setChartDomIns(myChart);
    DragLineFunc({
      myChart: myChart,
      id: lineId,
      yAxisData: hourData,
      limitData: limitData,
      updatePosition: () => {
        updatePosition(myChart, hourData);
      },
      dragChangeList: (yAxisData) => {
        setHourData(
          yAxisData.map((item) => {
            setHasModified(true);
            return parseFloat(item).toFixed(2);
          }),
        );
      },
    });
  };

  /**
   * 在 table 中改变自定义价格
   * @param {*} value 值
   * @param {*} index 索引
   */
  const changeCustomPrice = (value, index) => {
    let data = JSON.parse(JSON.stringify(hourData));
    data[index] = value;
    setHourData(data);
    setHasModified(true);

    chartDomIns.setOption({
      series: [
        {
          id: lineId,
          data: data,
        },
      ],
    });

    updatePosition(chartDomIns, data);
  };

  const SaveCustomForecastAsync = async () => {
    if (!selectedStationIds.length) {
      return TRMessage.warning('请选择交易单元');
    }
    setLoading(true);
    let priceList = hourData;
    /* if (pointType === '24') {
      let data = [];
      priceList.forEach((item) => {
        for (let i = 0; i < 4; i++) {
          data.push(item);
        }
      });
      priceList = data;
    } */
    const params = {
      dataTimeOrderType: pointType,
      date: date,
      marketId: 'PHBSX',
      stationIds: selectedStationIds,
      revisePrices: priceList,
      tradeSequenceId,
      stationId: defaultStationIds[0],
      version: version,
    };
    setLoading(false);
    let res = await saveRevisePrice(params);
    if (res?.statusCode === HttpCode.SUCCESS) {
      TRMessage.success('设置成功');
      setLoading(false);
      setShowModal(false);
      onChange(res?.data);
    } else {
      TRMessage.error(res?.message || '设置失败');
      setLoading(false);
    }
  };

  const cancelHandle = async () => {
    if (hasModified) {
      let obj = await TRAlert.show('当前工作将不被保存，继续执行此操作？');
      if (obj.index === 0) return;
    }

    setShowModal(false);
  };

  return (
    <Modal
      className={styles.CustomPriceForecast}
      centered={true}
      getContainer={true}
      title={
        <div className={styles.modalTitle}>
          <img src={configModal} />
          <span className={styles.text}>自主调整价格预测</span>
        </div>
      }
      visible={showModal}
      cancelText="返回"
      okText="保存并返回"
      confirmLoading={loading}
      onCancel={cancelHandle}
      onOk={SaveCustomForecastAsync}
    >
      <div className={styles.operate}>
        <div className={styles.date}>
          <span className={styles.label}>预测标的日</span>
          <span className={styles.value}>{date?.replaceAll('-', '')}</span>
        </div>
        <Pointer
          className={styles.pointer}
          data={pointType}
          onChange={(e) => {
            setPointType(e.target.value);
            setHasModified(true);
          }}
        />
        <div className={styles.blank} />
        <div className={styles.station}>
          <span className={styles.label}>预测适用单元</span>
          <StationSelector
            className={styles.stationSelector}
            menuCode="DayRollingTradeStrategy"
            selectedStationIds={selectedStationIds}
            provinceId={provinceId}
            onChange={(value) => {
              setSelectedStationIds(value);
              setHasModified(true);
            }}
          />
        </div>
      </div>
      <div id="customEchart" className={styles.echartsLine}>
        {''}
      </div>
      <Table
        className={styles.customPriceTable}
        dataSource={tableData}
        pagination={false}
        locale={tableLocale}
        bordered={true}
        scroll={{
          x: 752,
        }}
        rowKey="index"
      >
        {xAxisData?.[pointType]?.map((item, index) => {
          return (
            <Column
              align="center"
              title={item}
              dataIndex={item}
              key={item}
              width={74}
              render={(text) => {
                return (
                  <InputNumber
                    min={limitData[index]?.min}
                    max={limitData[index]?.max}
                    precision={2}
                    className={styles.input}
                    value={text}
                    onChange={(value) => {
                      changeCustomPrice(value || limitData[index]?.min, index);
                    }}
                  />
                );
              }}
            />
          );
        })}
      </Table>
    </Modal>
  );
}
